package org.robot.scm.platform.server;

import com.sun.net.httpserver.HttpServer;
import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import lombok.extern.slf4j.Slf4j;
import org.robot.scm.platform.AbstractMonitor;
import org.robot.scm.platform.ReflectionLoader;
import org.robot.scm.platform.server.handler.BaseHandler;
import org.robot.scm.platform.server.handler.GlobeInterceptor;
import org.robot.scm.pojos.config.BaseConfig;
import org.robot.scm.pojos.enums.PlatformEnum;
import org.robot.scm.utils.StreamUtils;

@Slf4j
public class ScmHttpServer {

    public static void start() {
        if (!AbstractMonitor.mainConfig.getEnables().contains(PlatformEnum.HTTP.getVal())) {
            return;
        }
        BaseConfig targetConfig = getTargetConfig(PlatformEnum.HTTP);
        String hostPort = targetConfig.getCurrentPlatform().getNoticeSrc();
        try {
            HttpServer server = HttpServer.create(new InetSocketAddress(Integer.parseInt(hostPort)), 0);
            server.createContext("/", new GlobeInterceptor(handleMap()));
            server.start();
            log.info(PlatformEnum.HTTP.getVal().concat(" started at {} ... ok"), hostPort);
        } catch (Exception e) {
            log.error("server start error", e);
        }
    }

    /**
     * context
     */
    private static Map<String, BaseHandler> handleMap() {
        return new HashMap<>() {
            {
                List<? extends BaseHandler> handlers = ReflectionLoader.load(BaseHandler.class);
                if (StreamUtils.count(StreamUtils.groupBy(handlers, BaseHandler::getUri).values(), list -> list.size() > 1) > 0) {
                    throw new RuntimeException("duplicate uri, please check");
                }
                handlers.forEach(handler -> put(handler.getUri(), handler));
            }
        };
    }

    /**
     * 读取当前平台的配置信息
     */
    public static BaseConfig getTargetConfig(PlatformEnum platform) {
        return new BaseConfig(AbstractMonitor.mainConfig, AbstractMonitor.mainConfig.getPlatform(platform));
    }
}
